import { Transaction } from "tiny-entity2";
import { IQueryObject } from "tiny-entity2/queryObject";
import { ServiceException } from "../common/excpetion";
import { ApiDataContext } from "../domain/apiDataContext";
import { Department } from "../domain/models/department";
import { BaseService, QueryParamsBase } from "./baseService";

export class DepartmentService extends BaseService {
    async CreateDepartment(entity: Department, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let has = await ctx.Department.Any(x => x.name == $args1 && x.organizationId == $args2 && x.isDelete ==$args3, 
                { $args1: entity.name, $args2: entity.organizationId , $args3: false});

            if (has) {
                throw new ServiceException(`已经存在名称为【${entity.name}】的部门！`);
            }
          

            let d = new Department();
            d.ConverToEntity(entity);
            return ctx.Create(d);
        });
    }
    async UpdateDepartment(entity: Department, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let has = await ctx.Department.Any(x => x.name == $args1 && x.organizationId == $args2 && x.id != $args4 && x.isDelete ==$args3, 
                { $args1: entity.name, $args2: entity.organizationId , $args3: false, $args4: entity.id});

            if (has) {
                throw new ServiceException(`已经存在名称为【${entity.name}】的部门！`);
            }

            let d = new Department();
            d.ConverToEntity(entity);
            return ctx.Update(d);
        });
    }
    async DeleteDepartment(entity: Department, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new Department();
            d.ConverToEntity(entity);
            return ctx.Delete(d);
        });
    }
    async GetDepartmentById(id: string) {
        let ctx = new ApiDataContext();
        return ctx.Department.First(x => x.id == $args1, { $args1: id });
    }
    async QueryDepartment(params: DepartmentQueryParams) {
        let q = this.GetQueryDepartmentCtx(params);
        let total = await q.Count();

        let q2 = this.GetQueryDepartmentCtx(params);
        if (params.countOfPage && params.pageIndex) {
            q2 = q2.Take(params.countOfPage).Skip(params.pageIndex - 1) as any;
        }
        let list = await q2.OrderByDesc(x=>x.createTime).ToList();

        return {
            total,
            list
        };
    }

    private GetQueryDepartmentCtx(params: DepartmentQueryParams) {
        let ctx = new ApiDataContext();
        let q = ctx.Department as IQueryObject<Department>;
        q=q.Where(x=>x.isDelete==$args1,{$args1:false});
        q=q.Where(x=>x.organizationId==$args1,{$args1:params.organizationId});
        if (params) {
            if (params.name) {
                q = q.Where(x => x.name.indexOf($args1), { $args1: params.name });
            }
        }
        return q;
    }
}

export interface DepartmentQueryParams extends QueryParamsBase {
    name?: string;
    organizationId:string;
}